package java8;

import org.junit.Test;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test2 {
    private static List<Employee> employees = new ArrayList<>();
    static {
        employees.add(new Employee(1001,"Tom",23,5600.0));
        employees.add(new Employee(1002,"BaiDu",12,7000.0));
        employees.add(new Employee(1003,"Alibaba",10,2000.0));
        employees.add(new Employee(1004,"Tencent",21,300.0));
    }


    @Test
    public void test2() {
        Employee emp = new Employee(1001,"Tom",23,5600.0);
        Supplier<String> sup1 = () -> emp.getName();
        System.out.println(sup1.get());
        System.out.println("*******************");

        Supplier<String> sup2 = emp::getName;
        System.out.println(sup2.get());

        Function<Employee,Double> func3 = Employee::getSalary;
        System.out.println(func3.apply(emp));
    }

    @Test
    public void test5() {
        Comparator<String> com1 = (s1, s2) -> s1.compareTo(s2);
        System.out.println(com1.compare("abc","abd"));
        System.out.println("*******************");

        Comparator<String> com2 = String::compareTo;
        System.out.println(com2.compare("abc","abe"));

    }

    @Test
    public void test4() {
        Function<Double,Long> func1 = d -> Math.round(d);
        System.out.println(func1.apply(12.3));
        System.out.println("*******************");

        Function<Double,Long> func2 = Math::round;
        System.out.println(func2.apply(19.1234));;
    }

    @Test
    public void test7() {
        Employee employee1 = new Employee(1001, "Jerry", 23, 6000.0);
        Function<Employee,String> func1 = f -> f.getName();
        System.out.println(func1.apply(employee1));
        System.out.println("*******************");
        Employee employee2 = new Employee(1001, "tom", 23, 6000.0);
        Function<Employee,Double> func2 = Employee ::getSalary;
        System.out.println(func2.apply(employee2));

    }


    public  String getObject(Supplier<String> supplier){
        return supplier.get();
    }


    @Test
    public void testSupplier(){
        Employee employee1 = new Employee(1001, "Jerry", 23, 6000.0);
        System.out.println(getObject(()->employee1.getName() + "我要回家"));
    }

    @Test
    public void testFunction() {
        int result = plusTwo(6, (x) -> x + 2);
        System.out.println(result);

        int before = before(6, x -> x + 2, x -> x * 10);
        // 62
        System.out.println(before);

        int after = after(6, x -> x + 2, x -> x * 10);
        // 80
        System.out.println(after);
    }
    public Integer plusTwo(int origen, Function<Integer, Integer> function) {
        return function.apply(origen);
    }
    public Integer before(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        // value作为function2的参数，返回一个结果，该结果作为function1的参数，返回一个最终结果
        Function<Integer, Integer> compose = function1.compose(function2);
        Integer apply = compose.apply(value);
        return apply;
    }
    public Integer after(int value, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        // value作为function1的参数，返回一个结果，该结果作为function2的参数，返回一个最终结果
        Function<Integer, Integer> integerIntegerFunction = function1.andThen(function2);
        return integerIntegerFunction.apply(value);
    }


    @Test
    public void test9(){
        List<Double> list = new ArrayList<>();
        list.add(0.0);
        list.add(9.01);
        list.add(9.89);
        list.add(9.0);
        list.add(9.33);
        double sum = list.stream().mapToDouble(e -> e).sum();
        double sum2 = list.stream().collect(Collectors.summingDouble(e->e));
        System.out.println(sum);
        System.out.println(sum2);

        DecimalFormat doubleFormatter = new DecimalFormat("#.00");
        doubleFormatter.setRoundingMode(RoundingMode.HALF_UP);
        System.out.println(doubleFormatter.format(sum2));



    }

    //映射
    @Test
    public void test11(){
        //map(Function f)——接收一个函数作为参数，将元素转换成其他形式或提取信息，该函数会被应用到每个元素上，并将其映射成一个新的元素。
        List<String> list = Arrays.asList("aa", "bb", "cc", "dd");
        list.stream().map(str->str + " hello").forEach(System.out::println);
        System.out.println();

        //练习1：获取员工姓名长度大于3的员工的姓名。

        employees.stream().map(Employee::getName).filter(name -> name.length() > 3).forEach(System.out::println);
        System.out.println();

        //练习2：
       /* Stream<Stream<Character>> streamStream = list.stream().map(SteamApi_02_use::fromStringToStream);
        streamStream.forEach( (s) -> System.out.println(s.collect(Collectors.toList())));
        System.out.println();*/



        //flatMap(Function f)——接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
        Stream<Character> characterStream = list.stream().flatMap(Test2::fromStringToStream);
        characterStream.forEach(System.out::println);
    }

    //将字符串中的多个字符构成的集合转换为对应的Stream的实例
    public static Stream<Character> fromStringToStream(String str){//aa
        ArrayList<Character> list = new ArrayList<>();
        for(Character c : str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }



}
